#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <memory>
#include "InetAddr.hpp"

class  Reactor;
//class Connection;

//using func_t = std::function<void(std::shared_ptr<Connection>)>;

// 为了解决每次读取时报文不完整而缓冲区直接释放的问题
// 为缓冲区提供对象，确保在收到完整报文后才读取；未读到
// 完整报文时保存起来，后续进行补充。

// 一个服务器会有很多的连接，描述连接，为其创建对象。
// 方便对连接进行后续管理。
class Connection
{
public:
    // 连接会有对应的fd
    Connection() : _sockfd(-1), _events(0)
    {
    }
    void UpdateTime()
    {
        //更新时间
    }
    void SetPeerInfo(const InetAddr &peer_addr)
    {
        _peer_addr = peer_addr;
    }
    void SetSockfd(int sockfd)
    {
        _sockfd = sockfd;
    }
    int Sockfd() { return _sockfd; }
    void SetEvents(uint32_t events) { _events = events; }
    uint32_t GetEvents() { return _events; }
    void SetOwner(Reactor *owner)
    {
        _owner = owner;
    }
    Reactor* GetOwner()
    {
        return _owner;
    }
    void Append(const std::string &in)
    {
        _inbuffer += in;
    }
    void AppendToOuT(const std::string &out)
    {
        _outbuffer += out;
    }
    //从发送缓冲区中剔除0~n个字节
    void DisCardOutString(int n)
    {
        _outbuffer.erase(0 ,n);
    }
    bool IsOutBufferEmpty() { return _outbuffer.empty(); }
    std::string &InBuffer()  
    {
        return _inbuffer;
    }
    std::string &OutString()  
    {
        return _outbuffer;
    }
    void Close()
    {
        if(_sockfd >= 0)
            ::close(_sockfd);
    }
    ~Connection()
    {
    }
    //回调方法不再采用智能指针，而是使用继承的方式
    virtual void Recver() = 0;
    virtual void Sender() = 0;
    virtual void Excepter() = 0;

protected:
    // 文件描述符分为两类：普通fd和Listensockfd。
    // 普通fd进行IO的，而Listensockfd是进行获取连接的
    // 处理方式是不太一样的

    // 这里让对fd的处理采用同一种方式，当然，也可以使用多态。

    int _sockfd;
    std::string _inbuffer;
    std::string _outbuffer;

    InetAddr _peer_addr; // 对应哪一个客户端

    // // 回调方法
    // func_t _recver; // 普通fd和listensockfd都可以采用读方法。
    // func_t _sender;
    // func_t _excepter;

    /// 添加一个指针
    Reactor *_owner;

    // Connection所关心的事件
    uint32_t _events;

    // lastmodtime
    uint64_t _timestamp;

};

// class Factory
// {
// public:
//     static std::shared_ptr<Connection> BuildConnection(int fd, uint32_t events, func_t r, func_t s, func_t e)
//     {
//         auto conn = std::make_shared<Connection>(fd);
//         conn->SetEvents(events);
//         conn->InitCB(r, s, e);
//         return conn;
//     }
// };
